package com.useeinfo.oa.modules.inspection.entity;

import com.alibaba.fastjson.JSONObject;
import com.useeinfo.framework.extend.entity.SuperClassEntity;
import com.useeinfo.framework.sugar.tools.StringConverters;
import com.useeinfo.oa.modules.base.entity.*;
import com.useeinfo.oa.modules.inspection.enums.InsOrderAssignTypeEnum;
import com.useeinfo.oa.modules.inspection.enums.InsPlannerStatusEnum;
import com.useeinfo.oa.modules.maintaining.entity.PeriodInstall;
import com.useeinfo.oa.modules.security.entity.SystemUser;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

import javax.persistence.*;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * 巡检-工单计划表
 */
@Entity
@Table(name = "planner_inspection")
public class PlannerInspection extends SuperClassEntity<PlannerInspection> {

    /**
     * 流水号
     */
    private String serial;
    /**
     * 工单名
     */
    private String name;
    /**
     * 计划状态
     */
    @Enumerated(value = EnumType.STRING)
    @Column(name = "planner_Status")
    private InsPlannerStatusEnum insPlannerStatusEnum = InsPlannerStatusEnum.START;
    /**
     * 计划开始时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date startTime;//精确到日
    /**
     * 计划结束时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date endTime;//精确到日
    /**
     * 计划已安排到日期
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date PlannerDate;
    /**
     * 计划周期
     */
    @ManyToOne
    @JoinColumn(name = "install_id")
    private PeriodInstall periodInstall;

    /**
     * 提醒时间
     */
    private int remindTime = 2;
    /**
     * 工作要求
     */
    private String required;
    /**
     * 标准工分
     */
    private Long points;
    /**
     * 紧急程度
     */
    private String degree;
    /**
     * 工单类型
     */
    private String type;
    /**
     * 安全指导书
     */
    private boolean safeInstruction = false;

    /**
     * 安全指导书pdf
     */
    @ManyToOne
    @JoinColumn(name = "resource_id")
    private Resource resource;

    /**
     * 所属企业
     */
    @ManyToOne
    @JoinColumn(name = "enterprise_id")
    private Enterprise enterprise;
    /**
     * 所属部门
     */
    @ManyToOne
    @JoinColumn(name = "organization_id")
    private Organization organization;

    /**
     * 指派类型
     */
    @Enumerated(value = EnumType.STRING)
    @Column(name = "order_assign_type")
    private InsOrderAssignTypeEnum insOrderAssignTypeEnum;

    /**
     * 是否指派
     */
    @Column(columnDefinition = "bit default 0")
    private boolean assign = false;

    /**
     * 指派人
     */
    @ManyToMany(fetch = FetchType.LAZY)
    @LazyCollection(LazyCollectionOption.FALSE)
    @JoinTable(name = "inspection_assign_users", joinColumns = {
            @JoinColumn(name = "inspection_planner_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")})
    private Set<SystemUser> assignUsers = new HashSet<>();

    /**
     * 指派岗位
     */
    @ManyToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    @JoinTable(name = "inspection_assign_positions", joinColumns = {
            @JoinColumn(name = "inspection_planner_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")})
    private Set<Position> assignPositions = new HashSet<>();
    /**
     * 计划创建人
     */
    @ManyToOne
    @JoinColumn(name = "create_user_id")
    private SystemUser createUser;

    /**
     * 完成审批流（将审批节点以json传入）
     */
    private String completeFlow;
    /**
     * 完成审批流
     */
    @ManyToOne
    @JoinColumn(name = "audit_complete")
    private AuditFlow auditComplete;

    /**
     * 延期审批流（将审批节点以json传入）
     */
    private String delayFlow;
    /**
     * 延期审批流
     */
    @ManyToOne
    @JoinColumn(name = "audit_delay")
    private AuditFlow auditDelay;
    /**
     * 取消审批流（将审批节点以json传入）
     */
    private String cancelFlow;
    /**
     * 取消审批流
     */
    @ManyToOne
    @JoinColumn(name = "audit_cancel")
    private AuditFlow auditCancel;

    /**
     * 工单关联设备和工艺
     */
    @OneToMany(mappedBy = "plannerInspection", fetch = FetchType.LAZY)
    private Set<FacilityInspection> facilityInspections = new HashSet<>();

    /**
     * 是否顺延
     *
     * @return
     */
    private boolean delay = false;

    /**
     * 顺延时间
     *
     * @return
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date delayDate;

    @Override
    public JSONObject toJSONObject() {
        JSONObject jsonObject = super.toJSONObject();
        jsonObject.put("serial", StringConverters.null2String(getSerial()));
        jsonObject.put("name", StringConverters.null2String(getName()));
        jsonObject.put("installName", StringConverters.null2String(getPeriodInstall() != null ? getPeriodInstall().getName() : ""));
        jsonObject.put("startTime", StringConverters.formatShortDate(getStartTime()));
        jsonObject.put("endTime", StringConverters.formatShortDate(getEndTime()));
        jsonObject.put("remindTime", StringConverters.null2String(getRemindTime()));
        jsonObject.put("required", StringConverters.null2String(getRequired()));
        jsonObject.put("plannerStatus", getInsPlannerStatusEnum() != null ? getInsPlannerStatusEnum().getName() : "");
        jsonObject.put("enterpriseName", StringConverters.null2String(getEnterprise().getEnterpriseName()));
        jsonObject.put("assign", isAssign() ? "是" : "否");
        jsonObject.put("assignType", getInsOrderAssignTypeEnum() != null && isAssign() ? (getInsOrderAssignTypeEnum().getCode().equals("USER") ? "指派人员" : "指派岗位") : "未指派");

        return jsonObject;
    }

    public String getSerial() {
        return serial;
    }

    public void setSerial(String serial) {
        this.serial = serial;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public InsPlannerStatusEnum getInsPlannerStatusEnum() {
        return insPlannerStatusEnum;
    }

    public void setInsPlannerStatusEnum(InsPlannerStatusEnum insPlannerStatusEnum) {
        this.insPlannerStatusEnum = insPlannerStatusEnum;
    }

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public Date getPlannerDate() {
        return PlannerDate;
    }

    public void setPlannerDate(Date plannerDate) {
        PlannerDate = plannerDate;
    }

    public PeriodInstall getPeriodInstall() {
        return periodInstall;
    }

    public void setPeriodInstall(PeriodInstall periodInstall) {
        this.periodInstall = periodInstall;
    }

    public int getRemindTime() {
        return remindTime;
    }

    public void setRemindTime(int remindTime) {
        this.remindTime = remindTime;
    }

    public String getRequired() {
        return required;
    }

    public void setRequired(String required) {
        this.required = required;
    }

    public Long getPoints() {
        return points;
    }

    public void setPoints(Long points) {
        this.points = points;
    }

    public String getDegree() {
        return degree;
    }

    public void setDegree(String degree) {
        this.degree = degree;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isSafeInstruction() {
        return safeInstruction;
    }

    public void setSafeInstruction(boolean safeInstruction) {
        this.safeInstruction = safeInstruction;
    }

    public Resource getResource() {
        return resource;
    }

    public void setResource(Resource resource) {
        this.resource = resource;
    }

    public Enterprise getEnterprise() {
        return enterprise;
    }

    public void setEnterprise(Enterprise enterprise) {
        this.enterprise = enterprise;
    }

    public Organization getOrganization() {
        return organization;
    }

    public void setOrganization(Organization organization) {
        this.organization = organization;
    }

    public InsOrderAssignTypeEnum getInsOrderAssignTypeEnum() {
        return insOrderAssignTypeEnum;
    }

    public void setInsOrderAssignTypeEnum(InsOrderAssignTypeEnum insOrderAssignTypeEnum) {
        this.insOrderAssignTypeEnum = insOrderAssignTypeEnum;
    }

    public boolean isAssign() {
        return assign;
    }

    public void setAssign(boolean assign) {
        this.assign = assign;
    }

    public Set<SystemUser> getAssignUsers() {
        return assignUsers;
    }

    public void setAssignUsers(Set<SystemUser> assignUsers) {
        this.assignUsers = assignUsers;
    }

    public Set<Position> getAssignPositions() {
        return assignPositions;
    }

    public void setAssignPositions(Set<Position> assignPositions) {
        this.assignPositions = assignPositions;
    }

    public SystemUser getCreateUser() {
        return createUser;
    }

    public void setCreateUser(SystemUser createUser) {
        this.createUser = createUser;
    }

    public String getCompleteFlow() {
        return completeFlow;
    }

    public void setCompleteFlow(String completeFlow) {
        this.completeFlow = completeFlow;
    }

    public AuditFlow getAuditComplete() {
        return auditComplete;
    }

    public void setAuditComplete(AuditFlow auditComplete) {
        this.auditComplete = auditComplete;
    }

    public String getDelayFlow() {
        return delayFlow;
    }

    public void setDelayFlow(String delayFlow) {
        this.delayFlow = delayFlow;
    }

    public AuditFlow getAuditDelay() {
        return auditDelay;
    }

    public void setAuditDelay(AuditFlow auditDelay) {
        this.auditDelay = auditDelay;
    }

    public String getCancelFlow() {
        return cancelFlow;
    }

    public void setCancelFlow(String cancelFlow) {
        this.cancelFlow = cancelFlow;
    }

    public AuditFlow getAuditCancel() {
        return auditCancel;
    }

    public void setAuditCancel(AuditFlow auditCancel) {
        this.auditCancel = auditCancel;
    }

    public Set<FacilityInspection> getFacilityInspections() {
        return facilityInspections;
    }

    public void setFacilityInspections(Set<FacilityInspection> facilityInspections) {
        this.facilityInspections = facilityInspections;
    }

    public boolean isDelay() {
        return delay;
    }

    public void setDelay(boolean delay) {
        this.delay = delay;
    }

    public Date getDelayDate() {
        return delayDate;
    }

    public void setDelayDate(Date delayDate) {
        this.delayDate = delayDate;
    }
}
